package medialistfor_mobile

import (
	"fmt"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/pkg/errors"
	"gitlab.local/golibrary/utils"
)

// DataList 获取相应的数据列表
func (m *Mobile) DataList(data List, userName string) (interface{}, error) {
	err := m.start()
	if err != nil {
		return nil, err
	}
	count, _ := strconv.Atoi(data.Per)
	page, _ := strconv.Atoi(data.Page)
	start := (page - 1) * count
	return m.forDataDesc(data.Type, data.Sort, data.Desc, "", userName, count, start)
}

func (m *Mobile) forDataDesc(db, sort, isDesc, where, userName string, limit, offset int) (interface{}, error) {
	database := m.media.Table(db)
	sql := m.sortType(sort, isDesc)
	if sql == "" {
		return nil, errors.New("Sort Type is wrong")
	}

	switch db {
	case "photo":

		result := make([]Photo, 0)
		err := database.Where("type = 0 and (path like ? or path like ?)",
			"/Volume%", "/home/"+userName+"/%").Order(sql).Limit(limit).Offset(offset).Find(&result).Error

		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		permissionPhotos := make([]Photo, 0)
		AclPathList := make(UserPermissionsInPath, 0)
		for _, photo := range result {
			folderPath := FolderPath(filepath.Dir(photo.Path))

			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), userName)
			}

			if !(AclPathList[folderPath].Username == userName && AclPathList[folderPath].IsPermissions) {
				continue
			}

			permissionPhotos = append(permissionPhotos, photo)
		}

		return permissionPhotos, err
	case "music":

		result := make([]Music, 0)
		err := database.Where("path like ? or path like ?",
			"/Volume%", "/home/"+userName+"/%").Order(sql).Limit(limit).Offset(offset).Find(&result).Error

		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		permissionMusics := make([]Music, 0)
		AclPathList := make(UserPermissionsInPath, 0)

		for _, music := range result {
			folderPath := FolderPath(filepath.Dir(music.Path))

			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), userName)
			}

			if !(AclPathList[folderPath].Username == userName && AclPathList[folderPath].IsPermissions) {
				continue
			}

			permissionMusics = append(permissionMusics, music)
		}

		return permissionMusics, err
	case "video":

		result := make([]Video, 0)
		err := database.Where("path like ? or path like ?",
			"/Volume%", "/home/"+userName+"/%").Order(sql).Limit(limit).Offset(offset).Find(&result).Error

		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		permissionVideos := make([]Video, 0)
		AclPathList := make(UserPermissionsInPath, 0)

		for _, video := range result {
			folderPath := FolderPath(filepath.Dir(video.Path))

			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), userName)
			}

			if !(AclPathList[folderPath].Username == userName && AclPathList[folderPath].IsPermissions) {
				continue
			}

			permissionVideos = append(permissionVideos, video)
		}

		return permissionVideos, err
	case "documents":
		result := make([]Documents, 0)
		var err error
		if where == "" {
			err = database.Where("path like ? or path like ?",
				"/Volume%", "/home/"+userName+"/%").Order(sql).Limit(limit).Offset(offset).Find(&result).Error
		} else {
			err = database.Where("(path like ? or path like ?) and type like ?",
				"/Volume%", "/home/"+userName+"/%", where+"%").Order(sql).Limit(limit).Offset(offset).Find(&result).Error
		}

		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		permissionDocuments := make([]Documents, 0)
		AclPathList := make(UserPermissionsInPath, 0)

		for _, document := range result {
			folderPath := FolderPath(filepath.Dir(document.Path))

			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), userName)
			}

			if !(AclPathList[folderPath].Username == userName && AclPathList[folderPath].IsPermissions) {
				continue
			}

			permissionDocuments = append(permissionDocuments, document)
		}

		return permissionDocuments, err
	}

	return nil, errors.New("DBType is wrong")
}

func (m *Mobile) sortType(sort, isDesc string) string {
	switch sort {
	case "name":
		return m.nameDescType(isDesc)
	case "time":
		return m.timeDescType(isDesc)
	}
	return ""
}

func (m *Mobile) timeDescType(isDesc string) string {
	sql := "TIMESTAMP DESC"
	if isDesc == "false" {
		sql = "TIMESTAMP ASC"
	}
	return sql
}

func (m *Mobile) nameDescType(isDesc string) string {
	sql := "NAME DESC"
	if isDesc == "false" {
		sql = "NAME ASC"
	}
	return sql
}

func (m *Mobile) DocxList(data List, userName string) (interface{}, error) {
	err := m.start()
	if err != nil {
		return nil, err
	}
	count, _ := strconv.Atoi(data.Per)
	page, _ := strconv.Atoi(data.Page)
	start := (page - 1) * count
	return m.forDataDesc("documents", data.Sort, data.Desc, data.Type, userName, count, start)
}

func (m *Mobile) Search(fileType, content, docType, user string) (interface{}, error) {

	db := m.media
	switch fileType {
	case "photo":

		result := make([]Photo, 0)
		err := db.Debug().Where("type = 0 and (path like ? or path like ?) and name like ?",
			"/Volume%", "/home/"+user+"/%", "%"+content+"%").Find(&result).Error
		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		res := make([]Photo, 0)
		AclPathList := make(UserPermissionsInPath, 0)
		for _, k := range result {
			//判断当前用户是否有权限对于相应目录的照片具有读取权限
			folderPath := FolderPath(filepath.Dir(k.Path))
			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), user)
			}
			if !(AclPathList[folderPath].Username == user && AclPathList[folderPath].IsPermissions) {
				continue
			}
			res = append(res, k)
		}
		return res, nil
	case "video":

		result := make([]Video, 0)
		err := db.Debug().Where("(path like ? or path like ?) and name like ?",
			"/Volume%", "/home/"+user+"/%", "%"+content+"%").Find(&result).Error
		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		res := make([]Video, 0)
		AclPathList := make(UserPermissionsInPath, 0)
		for _, k := range result {
			//判断当前用户是否有权限对于相应目录的照片具有读取权限
			folderPath := FolderPath(filepath.Dir(k.Path))
			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), user)
			}
			if !(AclPathList[folderPath].Username == user && AclPathList[folderPath].IsPermissions) {
				continue
			}
			res = append(res, k)
		}
		return res, nil
	case "music":

		result := make([]Music, 0)
		err := db.Debug().Where("(path like ? or path like ?) and name like ?",
			"/Volume%", "/home/"+user+"/%", "%"+content+"%").Find(&result).Error
		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		res := make([]Music, 0)
		AclPathList := make(UserPermissionsInPath, 0)
		for _, k := range result {
			//判断当前用户是否有权限对于相应目录的照片具有读取权限
			folderPath := FolderPath(filepath.Dir(k.Path))
			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), user)
			}
			if !(AclPathList[folderPath].Username == user && AclPathList[folderPath].IsPermissions) {
				continue
			}
			res = append(res, k)
		}
		return res, nil
	case "file":

		result := make([]Documents, 0)
		var err error
		if docType == "" {
			err = db.Debug().Where("(path like ? or path like ?) and name like ?",
				"/Volume%", "/home/"+user+"%", "%"+content+"%").Find(&result).Error
		} else {
			err = db.Debug().Where("(path like ? or path like ?) and name like ? and type like ?",
				"/Volume%", "/home/"+user+"/%", "%"+content+"%", docType+"%").Find(&result).Error
		}
		if err != nil {
			return nil, err
		}

		if len(result) == 0 {
			return nil, errors.New("end of page")
		}

		res := make([]Documents, 0)
		AclPathList := make(UserPermissionsInPath, 0)
		for _, k := range result {
			//判断当前用户是否有权限对于相应目录的照片具有读取权限
			folderPath := FolderPath(filepath.Dir(k.Path))
			if _, ok := AclPathList[folderPath]; !ok {
				AclPathList[folderPath] = m.PermissionsInPath(string(folderPath), user)
			}
			if !(AclPathList[folderPath].Username == user && AclPathList[folderPath].IsPermissions) {
				continue
			}
			res = append(res, k)
		}

		return res, nil
	}
	return nil, errors.New("search failed")
}

// PermissionsInPath 获取FolderPath下的当前用户读取权限
func (m *Mobile) PermissionsInPath(path, user string) PathToUserAcl {
	var fileAcl PathToUserAcl

	// fileUserName, _, err := m.AclGetter.GetPathAclUserOrGroup(path)
	// if err != nil {
	// 	return fileAcl
	// }
	fileAcl.Username = user

	output, err := utils.ShellUserExec(user, fmt.Sprintf(`[ -r '%s' ] && echo r`, path))
	if err != nil {
		return fileAcl
	}
	if strings.Contains(output, "r") {
		fileAcl.IsPermissions = true
	}
	return fileAcl
}
